﻿using System;
using System.Xml.Linq;

using Perseus;
using Perseus.Xml;

using Hetymine.Executioner.Data;
using Hetymine.Executioner.Triggers;

namespace Hetymine.Executioner.Plugins.Triggers.DateTime {
    public class DateTimeTrigger : ITrigger {
        private DateTimeTriggerConfigurator _Configurator;

        public DateType DateType { get; set; }
        public Days Days { get; set; }
        public System.DateTime DateTime { get; set; }
        public bool FullScreenQueue { get; set; }

        #region ITrigger Members
        public bool IsEmpty {
            get { return false; }
        }

        public bool IsSelected { get; set; }

        public void Load(XElement element) {
            this.Days = Days.None;            

            this.FullScreenQueue = element.Attribute("FullScreenQueue").BoolOrFalse();

            if (element.Element("Date") == null) {
                this.DateType = DateType.Daily;
            }
            else {
                string dateType = element.Element("Date").Attribute("Type").ValueOr("Daily");

                switch (dateType) {
                    case "Weekly":
                        this.DateType = DateType.Weekly;
                        break;
                    case "Once":
                        this.DateType = DateType.Once;
                        break;
                    case "Daily":
                    default:
                        this.DateType = DateType.Daily;
                        break;
                }
            }

            if (this.DateType == DateType.Weekly) {
                if (element.Element("Date").Element("Monday") != null) {
                    this.Days |= Days.Monday;
                }
                if (element.Element("Date").Element("Tuesday") != null) {
                    this.Days |= Days.Tuesday;
                }
                if (element.Element("Date").Element("Wednesday") != null) {
                    this.Days |= Days.Wednesday;
                }
                if (element.Element("Date").Element("Thursday") != null) {
                    this.Days |= Days.Thursday;
                }
                if (element.Element("Date").Element("Friday") != null) {
                    this.Days |= Days.Friday;
                }
                if (element.Element("Date").Element("Saturday") != null) {
                    this.Days |= Days.Saturday;
                }
                if (element.Element("Date").Element("Sunday") != null) {
                    this.Days |= Days.Sunday;
                }
            }
            else if (this.DateType == DateType.Once) {
                string date = element.Element("Date").ValueOr(System.DateTime.Now.ToString("yyyy-MM-dd"));
                try {
                    this.DateTime = System.DateTime.Parse(date);
                }
                catch {
                    this.DateTime = System.DateTime.Today;
                }
            }

            System.DateTime time;
            if (element.Element("Time") == null) {
                time = System.DateTime.Now;
            }
            else {
                try {
                    time = System.DateTime.Parse(element.Element("Time").Value);
                }
                catch {
                    time = System.DateTime.Now;
                }
            }

            this.DateTime = this.DateTime.AddHours(time.Hour);
            this.DateTime = this.DateTime.AddMinutes(time.Minute);
            this.DateTime = this.DateTime.AddSeconds(time.Second);
        }

        public XElement Save() {
            if (this.IsEmpty) {
                return null;
            }

            XElement xe = new XElement("DateTime");
            xe.Add(new XAttribute("FullScreenQueue", this.FullScreenQueue));

            XElement date = new XElement("Date");

            switch (this.DateType) {
                case DateType.Daily:
                    date.Add(new XAttribute("Type", "Daily"));
                    break;
                case DateType.Weekly:
                    date.Add(new XAttribute("Type", "Weekly"));
                    if ((this.Days | Days.Monday) == this.Days) {
                        date.Add(new XElement("Monday"));
                    }
                    if ((this.Days | Days.Tuesday) == this.Days) {
                        date.Add(new XElement("Tuesday"));
                    }
                    if ((this.Days | Days.Wednesday) == this.Days) {
                        date.Add(new XElement("Wednesday"));
                    }
                    if ((this.Days | Days.Thursday) == this.Days) {
                        date.Add(new XElement("Thursday"));
                    }
                    if ((this.Days | Days.Friday) == this.Days) {
                        date.Add(new XElement("Friday"));
                    }
                    if ((this.Days | Days.Saturday) == this.Days) {
                        date.Add(new XElement("Saturday"));
                    }
                    if ((this.Days | Days.Sunday) == this.Days) {
                        date.Add(new XElement("Sunday"));
                    }
                    break;
                case DateType.Once:
                default:
                    date.Add(new XAttribute("Type", "Once"));
                    string sdate = this.DateTime.ToString("yyyy-MM-dd");
                    date.Value = sdate;
                    break;
            }

            xe.Add(date);

            // The time portion of the date
            string stime = this.DateTime.ToString("HH:mm:ss");
            XElement time = new XElement("Time", stime);
            xe.Add(time);

            return xe;
        }

        public IConfigurator<ITrigger> Configurator {
            get {
                if (this._Configurator == null) {
                    this._Configurator = new DateTimeTriggerConfigurator();
                }
                this._Configurator.InitializeConfig(this);
                return this._Configurator;
            }
        }

        public object Clone() {
            DateTimeTrigger t = (DateTimeTrigger)this.MemberwiseClone();            
            t._Configurator = null;
            return t;
        }
        #endregion
    }
}
